Buforowanie fragmentaryczne
================

Buforowanie fragmentaryczne odnosi się do buforowania części strony. Na przykład, 
jeśli strona wyświetla podsumowanie rocznej sprzedaży w tabelce, możemy zachować 
tą tabelkę w buforze, aby wyeliminować czas potrzebny do jej wygenerowania 
dla każdego żądania. 

Aby używać buforowania fragmentarycznego wywołujemy 
[CController::beginCache()|CBaseController::beginCache()] oraz
[CController::endCache()|CBaseController::endCache()] w pliku widoku kontrolera.
Te dwie metody, odpowiednio, zaznaczają początek oraz koniec zawartości strony, 
która powinna zostać zbuforowana. Tak jak dla [buforowania danych](/doc/guide/caching.data)
potrzebujemy ID do zidentyfikowania fragmentu, który będzie buforowany.

~~~
[php]
...pozostała zawartość HTML...
<?php if($this->beginCache($id)) { ?>
...zawartość, która będzie buforowana...
<?php $this->endCache(); } ?>
...pozostała zawartość HTML...
~~~

Powyżej, jeśli metoda [beginCache()|CBaseController::beginCache()] zwróci wartość
false, zbuforowana zawartość będzie automatycznie wstawiona w tym miejscu;
w przeciwnym przypadku, zawartość zawarta w wyrażeniu `if` będzie wykonana 
i zbuforowana do miejsca wywołania metody [endCache()|CBaseController::endCache()].

Opcje buforowania
---------------

Podczas wywoływania metody [beginCache()|CBaseController::beginCache()] możemy 
dostarczyć tablicy, jako drugiego parametru, zawierającej opcje buforowania w celu 
dostosowania do własnych potrzeb buforowania fragmentarycznego. Ze względu na 
fakt, że metody [beginCache()|CBaseController::beginCache()] oraz
[endCache()|CBaseController::endCache()] są wygodnymi wraperami widżetu  
[COutputCache], dlatego też, opcje buforowania mogą być wartościami początkowymi 
każdej z właściwości [COutputCache].

### Czas trwania

Prawdopodobnie najbardziej znaną opcją jest czas trwania [duration|COutputCache::duration],
która określa jak długo zawartość może pozostać poprawna dla bufora. Jest ona podobna 
do parametru wygasania metody [CCache::set()]. Następujący kod buforuje część 
zawartości na maksymalnie godzinę czasu:

~~~
[php]
...pozostała zawartość HTML...
<?php if($this->beginCache($id, array('duration'=>3600))) { ?>
...zawartość, która będzie cache'owana...
<?php $this->endCache(); } ?>
...pozostała zawartość HTML...
~~~

Jeśli nie ustalimy czasu trwania, będzie on domyślnie posiadał wartość 60,
co oznacza, że zawartość będzie niepoprawna po 60 sekundach.

Poczynając od wersji 1.1.8, jeśli czas trwania ustawiony jest na 0, cała zawartość
pamięci podręcznej zostanie usunięta z bufora. Jeżeli ustawiony czas trwania będzie
miał wartość ujemną, buforowanie zostanie wyłączone, jednakże istniejąca zawartość pamięci
podręcznej pozostanie w buforze. We wersjach poprzedzających 1.1.8, jeśli czas trwania 
ustawiony był na 0 lub wartość ujemną, bufor był wyłączany.

### Zależność

Jak w [buforowaniu danych](/doc/guide/caching.data) część buforowanej zawartości,
może także posiadać zależności. Na przykład, zawartość wyświetlanego postu, zależy
od tego, czy został on zmodyfikowany, czy też nie.

Aby określić zależność ustawiamy opcję [dependency|COutputCache::dependency],
która może być zarówno obiektem implementującym interfejs [ICacheDependency] 
jak i tablicą konfiguracyjną, która może zostać użyta do generowania obiektu zależności.
Następujący kod deklaruje część zawartości, zależną od zmian wartości w kolumnie
`lastModified`:

~~~
[php]
...other HTML content...
<?php if($this->beginCache($id, array('dependency'=>array(
		'class'=>'system.caching.dependencies.CDbCacheDependency',
		'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>
...zawartość, która będzie buforowana...
<?php $this->endCache(); } ?>
...other HTML content...
~~~

### Uzmiennianie

Zawartość, która będzie buforowana, może zostać zmieniona odpowiednio do pewnych
parametrów. Na przykład, profil osobisty, może wyglądać różnie dla różnych użytkowników.
Buforując zawartość profilu, będziemy chcieli uzmiennić zbuforowaną kopię, odpowiednio
do ID użytkowników. To w istocie oznacza, że będziemy chcieli używać różnych
ID podczas wołania metody [beginCache()|CBaseController::beginCache()].

Zamiast prosić dewelopera o uzmiennienie ID odpowiednio do pewnego wzorca, 
[COutputCache] posiada takie wbudowane funkcjonalności. Poniżej ich podsumowanie.

   - [varyByRoute|COutputCache::varyByRoute]: ustawiając tą opcję na true, buforowana
   zawartość będzie uzmienniona odpowiednio do [trasy](/doc/guide/basics.controller#route). 
   Dlatego, każda kombinacja żądanego kontrolera oraz akcji będzie posiadała oddzielnie
   zbuforowaną zawartość.

   - [varyBySession|COutputCache::varyBySession]: ustawiając tą opcję na true, 
   możemy uzmiennić buforowaną zawartość odpowiednio do ID sesji. Dlatego też, 
   każda sesja użytkownika może widzieć różną zawartość i wszystkie one są dostarczone 
   z bufora.

   - [varyByParam|COutputCache::varyByParam]: ustawiając tą opcję jako tablicę 
   nazw, możemy zawartość zbuforowaną uzmiennić odpowiednio do wartości parametrów
   GET. Na przykład, jeśli strona wyświetla zawartość posta, odpowiednio do parametru 
   GET o nazwie `id`, możemy określić jako [varyByParam|COutputCache::varyByParam] 
   tablicę `array('id')`, tak, że możemy zbuforować zawartość dla każdego posta.
   Bez takiej parametryzacji, będziemy mogli buforować tylko pojedynczy post.
   
   - [varyByExpression|COutputCache::varyByExpression]: ustawiając tą opcję jako wyrażenie PHP, możemy zbuforowaną
   zawartość uzmiennić w zależności od wyniku wyrażenia PHP.

### Typy żądań

Czasami chcemy aby buforowanie fragmentaryczne było możliwe tylko dla konkretnych
typów żądań. Na przykład, dla strony wyświetlającej formularz, chcemy buforować formularz
tylko wtedy, gdy żądamy dostępu do niego po raz pierwszy (poprzez żądanie GET).
Każde następne wyświetlenie formularza (poprzez żądanie POST) nie powinno być buforowane
ponieważ formularz może zawierać dane wprowadzone przez użytkownika. Aby to zrobić,
możemy określi opcję [requestTypes|COutputCache::requestTypes]:

~~~
[php]
...pozostała zawartość HTML...
<?php if($this->beginCache($id, array('requestTypes'=>array('GET')))) { ?>
...zawartość, która będzie buforowana...
<?php $this->endCache(); } ?>
...pozostała zawartość HTML...
~~~

Zagnieżdżone buforowanie
--------------

Buforowanie fragmentaryczne może być zagnieżdżone. Oznacza to, że buforowana 
część zawiera się wewnątrz większej części, która także jest buforowana. 
Na przykład, komentarze są buforowane w wewnętrznym buforze fragmentarycznym,
a ono jest buforowane razem z zawartością postu w zewnętrznym buforze fragmentarycznym.

~~~
[php]
...pozostała zawartość HTML...
<?php if($this->beginCache($id1)) { ?>
...zewnętrzna zawartość, która będzie buforowana...
	<?php if($this->beginCache($id2)) { ?>
	...wewnętrzna zawartość, która będzie buforowana...
	<?php $this->endCache(); } ?>
...zewnętrzna zawartość, która będzie buforowana...
<?php $this->endCache(); } ?>
...pozostała zawartość HTML...
~~~

Różne opcje buforowania mogą być ustawione dla zagnieżdżonych buforów. Na przykład,
wewnętrzny bufor i zewnętrzny bufor w powyższym przykładzie, mogą mieć ustawione 
różne wartości długości trwania. Kiedy dane zbuforowane w zewnętrznym buforze są
niepoprawne, wewnętrzny bufor może wciąż dostarczać poprawą, wewnętrzną część.
Jednakże, nie jest to prawdą, jeśli sytuacja się odwróci. Jeśli zewnętrzny bufor
zawiera poprawne dane, będzie on zawsze dostarczał zbuforowaną kopię, nawet jeśli 
zawartość w wewnętrznym buforze wygaśnie.

<div class="revision">$Id: caching.fragment.txt 3315 2011-06-24 15:18:11Z qiang.xue $</div>